#include <iostream>
#include <functional>
#include <pthread.h>
using namespace std;

template <class T>
using func_t = function<void(T)>;

template <class T>
class Thread
{
public:
    Thread(string name, func_t<T> func, T arg)
        : _name(name), _tid(0), _isrunning(false), _func(func), _arg(arg)
    {}

    static void *threadroutine(void *arg)
    {
        ((Thread *)arg)->_func(((Thread *)arg)->_arg);
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, threadroutine, (void *)this);
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
    }

    void Join()
    {
        pthread_join(_tid, nullptr);
    }

    bool IsRunning()
    {
        return _isrunning;
    }

private:
    string _name;
    pthread_t _tid;
    bool _isrunning;
    func_t<T> _func;
    T _arg;
};